package com.csproj.system.service;


import com.csproj.siiat.security.SecurityUtils;
import com.csproj.system.domain.AuthorityInfo;
import com.csproj.system.repository.AuthorityInfoRepository;
import com.csproj.system.service.dto.AuthorityInfoDTO;
import com.csproj.system.service.mapper.AuthorityInfoMapper;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * Service Implementation for managing AuthorityInfo.
 */
@Service
@Transactional
public class AuthorityInfoService {

    //权限列表首级菜单的parnetCode
    private final static String PARENT_CODE_BY = "ROOT_";

    private final Logger log = LoggerFactory.getLogger(AuthorityInfoService.class);

    private final AuthorityInfoRepository authorityInfoRepository;

    private final AuthorityInfoMapper authorityInfoMapper;

    public AuthorityInfoService(AuthorityInfoRepository authorityInfoRepository, AuthorityInfoMapper authorityInfoMapper) {
        this.authorityInfoRepository = authorityInfoRepository;
        this.authorityInfoMapper = authorityInfoMapper;
    }

    /**
     * 保存权限
     *
     * @param authorityInfoDTO the entity to save
     * @return the persisted entity
     */
    public AuthorityInfoDTO save(AuthorityInfoDTO authorityInfoDTO) {
        log.debug("Request to save AuthorityInfo : {}", authorityInfoDTO);
        //添加操作记录

        AuthorityInfo authorityInfo = new AuthorityInfo();
        if(authorityInfoDTO.getId() != null) {

            authorityInfo = authorityInfoRepository.findOne(authorityInfoDTO.getId());
            authorityInfo.setCreatorUserId(SecurityUtils.getCurrentUserId());
            authorityInfo.setCreationTime(ZonedDateTime.now());
        }else{
            authorityInfo.setCreatorUserId(SecurityUtils.getCurrentUserId());
            authorityInfo.setCreationTime(ZonedDateTime.now());
        }

        authorityInfo.setName(authorityInfoDTO.getName());
        if(StringUtils.isBlank(authorityInfoDTO.getParentCode())){
            authorityInfoDTO.setParentCode("ROOT_");
        }
        authorityInfo.setParentCode(authorityInfoDTO.getParentCode());
        authorityInfo.setPermission(authorityInfoDTO.getPermission());
        authorityInfo.setRemark(authorityInfoDTO.getRemark());
        authorityInfo.setSort(authorityInfoDTO.getSort());
        authorityInfo.setDeletedFlag(false);
        authorityInfo = createCode(authorityInfo);
        authorityInfo = authorityInfoRepository.save(authorityInfo);

        AuthorityInfoDTO result = authorityInfoMapper.toDto(authorityInfo);
        return result;
    }

    /**
     *  获取所有的权限
     *
     *  @return the list of entities
     */
    @Transactional(readOnly = true)
    public List<AuthorityInfoDTO> findAll() {
        log.debug("Request to get all AuthorityInfos");
        List<AuthorityInfoDTO> result = authorityInfoRepository.findAll().stream()
            .map(ai -> authorityInfoMapper.toDto(ai)
//                .setIsShowName(ai.getIsShow())
            )
            .collect(Collectors.toCollection(LinkedList::new));

        return result;
    }

    /**
     *  获取一条权限
     *
     *  @param id the id of the entity
     *  @return the entity
     */
    @Transactional(readOnly = true)
    public AuthorityInfoDTO findOne(String id) {
        log.debug("Request to get AuthorityInfo : {}", id);
        AuthorityInfo authorityInfo = authorityInfoRepository.findOne(id);

        AuthorityInfoDTO authorityInfoDTO = authorityInfoMapper.toDto(authorityInfo);
//            .setIsShowName(isShow)

        return authorityInfoDTO;
    }

    /**
     *  删除权限
     *
     *  @param id the id of the entity
     */
    public void delete(String id) {
        log.debug("Request to delete AuthorityInfo : {}", id);
        //添加操作记录

        authorityInfoRepository.delete(id);
        AuthorityInfo authorityInfo = authorityInfoRepository.findOne(id);
        //保存用户操作
        //HttpClientUtil.request(new org.json.JSONObject(historyDTO).toString());
        //删除该权限下对应的子权限
        List<String> ids = authorityInfoRepository.findByCode(authorityInfo.getCode()).stream().map(n->{
            return n.getId();
        }).collect(Collectors.toCollection(LinkedList::new));
        if (ids.size() > 0) {
            authorityInfoRepository.deleteBatch(ids.toArray(new String[ids.size()]));
        }
    }

    /**
     * 查询所有的权限信息（不分页）
     * @date 2017-4-26
     * @param hsql          hsql语句
     * @param queryParams   参数
     * @return
     */
    public List<AuthorityInfoDTO> findAllList (String hsql, Map<String,Object> queryParams) {
        log.debug("Request to get all AuthorityInfos");
        List<AuthorityInfoDTO> result = authorityInfoRepository.findAllList(hsql,queryParams).stream()
            .map(ai -> authorityInfoMapper.toDto(ai)
//            .setIsShowName(ai.getIsShow())
            )
            .collect(Collectors.toCollection(LinkedList::new));
        return result;
    }
    /**
     * 根据知识点父级parent_code与id，创建code
     * @return  知识点信息
     */
    public AuthorityInfo createCode(AuthorityInfo authorityInfo){
        String parentCode = authorityInfo.getParentCode();
//        String id = authorityInfo.getId();
        Integer index = 1;
        String  codePre = authorityInfoRepository.findLastOneOrderByCreateTime();
        if(StringUtils.isNotBlank(codePre)){
            String[] codes = codePre.split("_");
            String codeIndexStr = codes[codes.length-1].replaceAll("[a-zA-Z]","");
            if(StringUtils.isNotBlank(codeIndexStr)){
                index=Integer.valueOf(codeIndexStr)+1;
            }
        }

        if("ROOT_".equals(parentCode) || "root_".equals(parentCode)){
            char ABC='A';
            String code = String.valueOf(ABC)+index+"_";
            authorityInfo.setCode(code);
            return authorityInfo;
        }

        int _index = parentCode.substring(0, parentCode.length()-2).lastIndexOf("_");
        if(_index == -1){
            String code = parentCode+"B"+index+"_";
            authorityInfo.setCode(code);
            return authorityInfo;
        }

        char ABC = parentCode.charAt(_index+1);
        String code = parentCode+String.valueOf((char)(ABC+1))+index+"_";
        authorityInfo.setCode(code);
        return authorityInfo;
    }

    public List<AuthorityInfoDTO> findByCurrentUserId() {
        List<AuthorityInfo> authoritys = authorityInfoRepository.findByUserInfoId(SecurityUtils.getCurrentUserId());
        List<AuthorityInfoDTO> authorityDTOs = authorityInfoMapper.toDto(authoritys);
        return authorityDTOs;
    }

    /**
     * 获取当前登录用户的权限菜单（树状结构）
     * @author wjf
     * @date 2017年8月7日 17:21:33
     */
    public List<AuthorityInfoDTO> findCurrentUserAuthorityInfoesWithTree(){
        String userInfoId = SecurityUtils.getCurrentUserId();
        List<AuthorityInfoDTO> authorityInfoDTOs = new ArrayList<>();
        List<AuthorityInfo> authorityInfos = getAuthorityInfoesWithTreeByUserInfoId(userInfoId);
        if(authorityInfos.size()==0){
            return authorityInfoDTOs;
        }
        //获取第一级的list集合
        List<AuthorityInfo> oneAuthorityInfos = authorityInfos.stream().filter(authorityInfo ->
            authorityInfo.getParentCode().equals(PARENT_CODE_BY)
//                    && authorityInfo.getIsShow()
        )//因为登录的是同一个页面，故可按ROOT_查找
            .collect(Collectors.toList());
        List<AuthorityInfoDTO> oneAuthorityInfoDTOs = authorityInfoMapper.toDto(oneAuthorityInfos);
        //获取第二级的list集合放到第一级里面
        oneAuthorityInfoDTOs.forEach(t->{
            List<AuthorityInfo> twoAuthorityInfos = authorityInfos.stream().filter(authorityInfo ->
                authorityInfo.getParentCode().equals(t.getCode())
//                        && authorityInfo.getIsShow()
            )
                .collect(Collectors.toList());
            List<AuthorityInfoDTO> twoAuthorityInfoDTOs = authorityInfoMapper.toDto(twoAuthorityInfos);
            t.setAuthorityInfoList(twoAuthorityInfoDTOs);
        });
        return oneAuthorityInfoDTOs;
    }
    /**
     * 根据用户id查询所拥有的权限列表（树状接口）
     */
    private List<AuthorityInfo> getAuthorityInfoesWithTreeByUserInfoId(String userInfoId){
        //当前登录用户的权限
        List<AuthorityInfo> authorityInfos = authorityInfoRepository.findByUserInfoId(userInfoId);
        //所有权限
        List<AuthorityInfo> allAuthorityInfos = authorityInfoRepository.findAll();
        //返回的树状结构结果
        List<AuthorityInfo> result=new ArrayList<>();
        for (AuthorityInfo au : allAuthorityInfos) {
            for (AuthorityInfo authorityInfo : authorityInfos) {
                if(authorityInfo.getCode().contains(au.getCode())){
                    result.add(au);
                    break;
                }
            }
        }
        return result ;
    }

    /**
     *  查找当前登录用户某权限下的的权限列表
     */
    public List<AuthorityInfoDTO> findCurrentUserChildAuthorityInfoesById(String id){
        List<AuthorityInfoDTO> result = new ArrayList<>();
        String userInfoId = SecurityUtils.getCurrentUserId();
        AuthorityInfo authorityInfo = authorityInfoRepository.findone(id);
        if(authorityInfo==null){
            return  result;
        }
        String code = authorityInfo.getCode();
        List<AuthorityInfo> authorityInfos = authorityInfoRepository.findByUserInfoIdAndParentCode(userInfoId,code);
        return authorityInfoMapper.toDto(authorityInfos);
    }
}
